import { localstorageDao } from './../utils/localstorage';
import { MessageBoxService, GrowlMessageType } from './messageBox';
import { KdsMessageType, FNCManager } from './../utils/fnc/fncManager';
import { Devices } from './../models/devices';
import { StoreSvr } from './../services/store';
import { AppStore } from './../services/appStore';
import { OrderSvr } from './../services/order';
import { ServiceBase } from './../services/base';
import { HostBinding, ChangeDetectorRef, state } from '@angular/core';
import { Component, ElementRef, AfterViewInit, OnDestroy, OnChanges, Input, Output, SimpleChange, EventEmitter } from '@angular/core';

@Component({
    selector: 'solution-config',
    styleUrls: [
        './components.scss'
    ],
    template: `
        <div [hidden]="!isShowKitchenSolutions">
            <div (click)="hiddenKitchenSolutions()" style="position: absolute;top:0;bottom:0;left:0;right:0;background: black;opacity: 0.4; z-index: 200;"></div> 
            <div id="J_kitchensolutions-config" class="kitchen-solutions" style=" position: absolute;bottom:2.8rem;left:2.6rem; z-index: 200;background:white;width:400px;">
                <header>
                    <p class="title">显示方案配置</p>
                    <i class="iconfont icon-clear" (click)="hiddenKitchenSolutions()"></i>
                </header>
                <section>
                    <p class="title">当前终端：{{currentDevice&&currentDevice.name}} ({{kitchenSolutionName}})</p>
                    <p class="content">合并显示其他终端</p>
                    <p class="layout-row" *ngFor="let device of devices;trackBy:trackById">
                        <span class="flex name">{{device.name}}</span>
                        <span class="btns">
                            <button (click)="closeChangeStall(currentDevice, device)"  [class.active]='!((currentDevice&&currentDevice.transferIn&&currentDevice.transferIn.indexOf(device&&device.id)>-1) || (currentDevice&&currentDevice.id)==device.transferOut)'>关</button>
                            <button (click)="mergeStall(currentDevice, device)" [class.active]='currentDevice&&currentDevice.transferIn&&currentDevice.transferIn.indexOf(device&&device.id)>-1&&(currentDevice.id!=device.transferOut)'>合并</button>
                            <button (click)="toggleTransferStall(currentDevice, device)" [class.active]='(currentDevice&&currentDevice.id)==device.transferOut' >转移</button>
                        </span>
                    </p>
                </section>
                <footer>
                    <button [disabled]='!(currentDevice&&currentDevice.transferIn&&currentDevice.transferIn.length>0)' (click)="closeChangeStalls(currentDevice, devices)" >取消全部</button>
                </footer>
            </div>
            <confirm [title]="title" [content]="content" [cancelHidden]=true [visible]="visible"></confirm>
        </div>
    `,
})
export class SolutionConfig {
    constructor(
        private svr: ServiceBase,
        private orderSvr: OrderSvr,
        public appStore: AppStore,
        public changeDetectorRef: ChangeDetectorRef,
        private storeSvr: StoreSvr,
    ) {
        SolutionConfigService.current.regist(this);
    }
    private devices: Array<Devices>;
    private currentDevice: Array<Devices>;
    private isShowKitchenSolutions: Boolean = false;
    visible = false;
    private _kitchenSolutionName: String;
    private title = "提示";
    private content = "显示方案合并后，所有被合并的终端终会显示合并后的显示方。<br>显示方案转移后，转移到的终端会增加显示被转移终端的显示方案。";
    public set kitchenSolutionName(name) {
        this._kitchenSolutionName = name;
        this.onSolutionConfigResult.emit({ kitchenSolutionName: this._kitchenSolutionName });
    };
    public get kitchenSolutionName() {
        return this._kitchenSolutionName;
    }
    @Output() onSolutionConfigResult = new EventEmitter<{ kitchenSolutionName: String }>();

    private hiddenKitchenSolutions() {
        this.isShowKitchenSolutions = false;
    }
    public async showKitchenSolutions() {
        await this.refreshDevices();
        this.isShowKitchenSolutions = true;
        this.kitchenSolutionName = await this.getCurrentKitchensolutionNames();
        if (!localstorageDao.get("hasShownKitchenSolutionsConfig")) {
            this.visible = true;
            localstorageDao.set("hasShownKitchenSolutionsConfig", true);
        }
    }
    private trackById(index: number, device) {
        return device.id;
    }
    async refreshDevices(deviceIds?: string[]) {
        if (!deviceIds) {
            const currentDeviceId = this.storeSvr.getCurrentDeviceId();
            const devices = await this.storeSvr.getKdsDevices();
            this.currentDevice = <any>devices.find(x => x.id == currentDeviceId);
            this.devices = devices.filter(x => x.id != currentDeviceId);
        } else {
            const devices = await this.storeSvr.getKdsDevices();
            deviceIds.forEach(v => {
                this.devices[this.devices.findIndex(x => x.id == v)] = devices.find(x => x.id == v);
            })
        }
    }
    private async closeChangeStall(currentDevice: Devices, targertDevice: Devices) {
        try {
            if (targertDevice.transferOut) {
                const newDevice = await this.storeSvr.cancelTransferDevice(targertDevice.id, currentDevice.id);
            } else {
                const newDevice = await this.storeSvr.unMergeKdsDevices(currentDevice.id, [targertDevice.id]);
            }
            await this.refreshDevices();
            FNCManager.Current.KdsMessageNotify(KdsMessageType.DeviceMessage, this.currentDevice);
            this.kitchenSolutionName = await this.getCurrentKitchensolutionNames();
            this.appStore.orderStore.actions.resetAllOrders();
        } catch (error) {
            MessageBoxService.current.Growl(GrowlMessageType.Error, "错误提示", error.message || error);
        }

    }
    private async mergeStall(currentDevice, targertDevice) {
        try {
            const newDevice = await this.storeSvr.mergeKdsDevices(currentDevice.id, [targertDevice.id]);
            this.currentDevice = newDevice;
            FNCManager.Current.KdsMessageNotify(KdsMessageType.DeviceMessage, this.currentDevice);
            this.kitchenSolutionName = await this.getCurrentKitchensolutionNames();
            this.appStore.orderStore.actions.resetAllOrders();
        } catch (error) {
            MessageBoxService.current.Growl(GrowlMessageType.Error, "错误提示", error.message || error);
        }

    }
    private async toggleTransferStall(currentDevice: Devices, targertDevice) {
        try {
            const newDevice = await this.storeSvr.transferDevice(targertDevice.id, currentDevice.id);
            await this.refreshDevices();
            FNCManager.Current.KdsMessageNotify(KdsMessageType.DeviceMessage, this.currentDevice);
            this.kitchenSolutionName = await this.getCurrentKitchensolutionNames();
            this.appStore.orderStore.actions.resetAllOrders();
        } catch (error) {
            MessageBoxService.current.Growl(GrowlMessageType.Error, "错误提示", error.message || error);
        }
    }
    private async closeChangeStalls(currentDevice, devices) {
        try {
            const ids = devices.filter(x => x.transferOut == currentDevice.id).map(x => x.id);
            await this.storeSvr.unMergeKdsDevices(currentDevice.id, currentDevice.transferIn.filter(x => ids.indexOf(x) == -1));
            await Promise.all(ids.map(x => this.storeSvr.cancelTransferDevice(x, currentDevice.id)))
            await this.refreshDevices();
            FNCManager.Current.KdsMessageNotify(KdsMessageType.DeviceMessage, this.currentDevice);
            this.kitchenSolutionName = await this.getCurrentKitchensolutionNames();
            this.appStore.orderStore.actions.resetAllOrders();
        } catch (error) {
            MessageBoxService.current.Growl(GrowlMessageType.Error, "错误提示", error.message || error);
        }
    }
    private async getCurrentKitchensolutionNames(): Promise<String> {
        const kitchensolutions = await this.storeSvr.getDeviceKitchensolutions(this.storeSvr.getCurrentDeviceId());
        this.storeSvr.currentKitchenSolutions = kitchensolutions;
        return kitchensolutions.map(x => x.name).join(" + ");
    }
}


export class SolutionConfigService {
    public static current = new SolutionConfigService();
    open() {
        this._component.showKitchenSolutions();
    }

    private _component;
    regist(component) {
        this._component = component;
        this._component.onSolutionConfigResult.subscribe(result => {
            this.onResult(result);
        })
    }

    getCurrentKitchensolutionNames() {
        return this._component.getCurrentKitchensolutionNames();
    }

    onResult: (result) => void
}